snowsoft.gibay._LOG.info("Loading class, 'snowsoft.gibay.ModelManager'");

/**
 * This class is a model operation in system.I think I'd better don't modify the "MODEL_**" document in other place,just in this class only. 
 * Here's a google gears db usage,I use google gears to persistent CDF models in memory
 * @author digitalghost.liu@gmail.com 
 */
jsx3.lang.Class.defineClass("snowsoft.gibay.ModelManager", null, [], function(ModelManager) {
	//shortcut to package
	var gibay = snowsoft.gibay;	
	//private varible defines DB instance for Google gears database
	var _DB = null;

	//CDF Document for recent items user viewed	
	var MODEL_RecentItems = null;
	/**
	 * getter for retrive MODEL_RecentItems CDF Document
	 */
	ModelManager.getRecentItems = function(){
		return MODEL_RecentItems;
	};


	//CDF Document for items watch list	
	var MODEL_WatchList = null;
	/**
	 * getter for retrive MODEL_WathList CDF Document
	 */
	ModelManager.getWatchList = function(){
		return MODEL_WatchList;
	};

	//CDF Document for category navigation path	
	var MODEL_NavPath = null;
	/**
	 * getter for retrive MODEL_WathList CDF Document
	 */
	ModelManager.getNavPath = function(){
		return MODEL_NavPath;
	};

	//CDF Document for sortType of item list,this is about category listings	
	var MODEL_SortType_CategoryListings = null;
	//CDF Document for sortType of item list,this is about keywords search	
	var MODEL_SortType_Keywords = null;
	//CDF Document for popular keywords
	var MODEL_PopularKeywords = null;
	
	
	//private method for make models in memory and in database synchronous
	var _syncLocalData = function(){
		gibay._LOG.info("It's time to syncohronize the memory and database");		
		
		//use stupid method to determine whether exists the model record row
		var existsRecentItem = 0;
		var rs = _DB.execute('select * from cdfraw_models where model_id = ? ',['MODEL_RecentItems']);
		while (rs.isValidRow()) {
  			rs.next();
			existsRecentItem ++;
		}
		rs.close();
		if(existsRecentItem > 0){
			//update exists record
			_DB.execute('update cdfraw_models set cdfxml = ?,timestamp = ? where model_id = ?',[MODEL_RecentItems.getXML(),new Date().getTime(),'MODEL_RecentItems']);
		}else{
			//insert a new record
			_DB.execute('insert into cdfraw_models values(?,?,?)',['MODEL_RecentItems',MODEL_RecentItems.getXML(),new Date().getTime()]);
		}

		var existsWatchList = 0;
		var rs = _DB.execute('select * from cdfraw_models where model_id = ? ',['MODEL_WatchList']);
		while (rs.isValidRow()) {
  			rs.next();
			existsWatchList++;
		}
		rs.close();
		if(existsWatchList > 0){
			//update exists record
			_DB.execute('update cdfraw_models set cdfxml = ?,timestamp = ? where model_id = ?',[MODEL_WatchList.getXML(),new Date().getTime(),'MODEL_WatchList']);
		}else{
			//insert a new record
			_DB.execute('insert into cdfraw_models values(?,?,?)',['MODEL_WatchList',MODEL_WatchList.getXML(),new Date().getTime()]);
		}

		gibay.APP.getJSXByName("lblLocalPersistInfo").setText('Data synced at '+new Date(),true);
	};

	//private method to fetch local persistent data
	var _initLocalData = function(){
		
		gibay._LOG.info("Initializing the google gears local persitent data...");	
		//check if exists the google gears plugin.	
		if (!window.google || !google.gears) {
			gibay.APP.getJSXByName("blkNoGearsNotify").setDisplay(jsx3.gui.Block.DISPLAYBLOCK,true);
			gibay.APP.getJSXByName("lblLocalPersistInfo").setColor('Grey',true);
			gibay.APP.getJSXByName("lblLocalPersistInfo").setText('Local persistent disabled',true);
			return;
  		}else{
			gibay.APP.getJSXByName("blkNoGearsNotify").setDisplay(jsx3.gui.Block.DISPLAYNONE,true);
			gibay.APP.getJSXByName("lblLocalPersistInfo").setText('Local persistent enabled',true);
			_DB = google.gears.factory.create('beta.database','1.0');
			_DB.open('temp_gibay');
			_DB.execute('create table if not exists cdfraw_models (model_id text,cdfxml text, timestamp int)');
			gibay.APP.getJSXByName("lblLocalPersistInfo").setText('local database initialized',true);

			//set a interval for models sync
			window.setInterval(_syncLocalData,60000);
			
		}

		//load local cdf status at app startup
		var rs = _DB.execute('select * from cdfraw_models where model_id = ? ',['MODEL_RecentItems']);
		while (rs.isValidRow()) {
			MODEL_RecentItems.loadXML(rs.fieldByName('cdfxml'));	
			break;
		}
		rs.close();

		rs = _DB.execute('select * from cdfraw_models where model_id = ? ',['MODEL_WatchList']);
		while (rs.isValidRow()) {
  			MODEL_WatchList.loadXML(rs.fieldByName('cdfxml'));	
			break;
		}
		rs.close();

		gibay.APP.getJSXByName("lblLocalPersistInfo").setText("Local data restored..include recent items and watchlist",true);
		

	};

	ModelManager.init = function(){
		gibay._LOG.info("Begin to construct MODEL_*...");
		//code for initialize the MODEL_*	
		MODEL_NavPath = jsx3.xml.CDF.Document.newDocument();
		MODEL_NavPath.insertRecord({jsxid:"-1",jsxtext:"All Categories",Name:"All Categories",CategoryLevel:"0"});
		gibay.APP.getCache().setDocument("MODEL_NavPath",MODEL_NavPath);

		MODEL_PopularKeywords = jsx3.xml.CDF.Document.newDocument();
		_loadPopularKeywords();
		gibay.APP.getCache().setDocument("MODEL_PopularKeywords",MODEL_PopularKeywords);	

		MODEL_RecentItems = jsx3.xml.CDF.Document.newDocument();
		gibay.APP.getCache().setDocument("MODEL_RecentItems",MODEL_RecentItems);		
		//alert(MODEL_RecentItems);
		MODEL_WatchList = jsx3.xml.CDF.Document.newDocument();
		gibay.APP.getCache().setDocument("MODEL_WatchList",MODEL_WatchList);		
		//alert(MODEL_RecentItems);

		MODEL_SortType_CategoryListings = jsx3.xml.CDF.Document.newDocument();
		MODEL_SortType_CategoryListings.load(gibay.APP.resolveURI("xml/MODEL_SortType_CategoryListings.xml"));
		gibay.APP.getCache().setDocument("MODEL_SortType_CategoryListings",MODEL_SortType_CategoryListings);
	
		MODEL_SortType_Keywords = jsx3.xml.CDF.Document.newDocument();
		MODEL_SortType_Keywords.load(gibay.APP.resolveURI("xml/MODEL_SortType_Keywords.xml"));
		gibay.APP.getCache().setDocument("MODEL_SortType_Keywords",MODEL_SortType_Keywords);

		//second init phase,fetch local persistent user data from google gears database; 
		_initLocalData();	
	};

	// Methods for CRUD operation recent items viewed by user
	ModelManager.addRecentItem = function(recItem){
		
		//Because the 'MODEL_RecentItems' also has a reference in app's cache,but you needn't update the model in app's cache,it's updated automaticly	
		MODEL_RecentItems.insertRecord(recItem);
		gibay._LOG.info("Add method invoked,MODEL_RecentItems changes.");	
	};
	ModelManager.delRecentItem = function(recID){
		//not implement	
		MODEL_RecentItems.deleteRecord(recID);
		gibay._LOG.info("Delete method invoked,MODEL_RecentItems changes.");	
	};

	
	//Methods for CRUD operation of user's watchlist;
	ModelManager.addWatchItem = function(recItem){
		MODEL_WatchList.insertRecord(recItem);
		gibay._LOG.info("Add method invoked,MODEL_WatchList changes.");	
	};
	ModelManager.delWatchItem = function(recID){
		MODEL_WatchList.deleteRecord(recID);
		gibay._LOG.info("Delete method invoked,MODEL_WatchList changes.");	
	};
	
	//Methods for CRUD operation of popular keywords;
	ModelManager.addPopularKeyword = function(recItem){
		MODEL_PopularKeywords.insertRecord(recItem);
		gibay._LOG.info("Add method invoked,MODEL_PopularKeywords changes.");	
	};
	ModelManager.delPopularKeyword = function(recID){
		MODEL_PopularKeywords.deleteRecord(recID);
		gibay._LOG.info("Delete method invoked,MODEL_PopularKeywords changes.");	
	};

	
	//private method: for internal calls
	_loadPopularKeywords = function(){
		
		//closure code for short operation	
		_loadOK = function(objEvent){
			var tTotal = ((new Date()).valueOf() - objEvent.target.startTime) / 1000;
			gibay._LOG.info("Call GetPopularKeywords service successful.."+tTotal+" secs");
			//code for convert ebay response format into CDF Document	
			var doc = gibay.APP.getCache().getDocument("MODEL_TempKeywords");
			var keywords = doc.getAttribute("Keywords");
			keywords = keywords.split(";");
			for(var i=0;i<keywords.length;i++){
				ModelManager.addPopularKeyword({jsxid:keywords[i],jsxtext:keywords[i]});	
			}
			gibay.publish({subject:snowsoft.gibay.Event.ON_MODELPOPULARKEYWORDSUPDATED,target:this});		
		};	
		_loadError = function(objEvent){
			var tTotal = ((new Date()).valueOf() - objEvent.target.StartTime) / 1000;
    		giaby._LOG.info("Get service error, 'Response':\n__________________\n" + objEvent.target.getInboundDocument() + "\n__________________\n response time: " + tTotal + " seconds.");
		};

		try{	
			var objService = null;
			objService = gibay.APP.loadResource("getpopularkeywords_xml");
			objService.setOperation("GetPopularKeywords");
			objService.startTime = (new Date()).valueOf();	
			objService.subscribe(jsx3.net.Service.ON_SUCCESS,_loadOK);	
			objService.subscribe(jsx3.net.Service.ON_ERROR,_loadError);
			gibay._LOG.info("Call GetPopularKeywords service....");
			objService.doCall();
		}catch(e){
			var objError = jsx3.lang.NativeError.wrap(e);
			alert(objError.getMessage());	
		}	

	};	
	
});

//subscribe handler method to relevant events
snowsoft.gibay.APP.subscribe(snowsoft.gibay.Event.ON_APPLOAD,snowsoft.gibay.ModelManager.init);

